using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;

using SBPweb.Themes.Windows.Skins;
using SBPweb.Themes.Windows;

namespace SBPweb.Controls.Windows.Form
{
	/// <summary>
	/// Class of FormCaption
	/// </summary>
	[ToolboxItem(false)]
	public partial class FormCaption : UserControl, ISkinnable
	{
		#region Private members

		private bool mUseDefaultSkin;
		private Skin mSkin;
		private Font mFont;

		#endregion

		#region Constructor logic

		public FormCaption()
		{
			InitializeLogic();
		}

		public FormCaption(Skin skin)
		{
			mSkin = skin;
			InitializeLogic();
		}

		public FormCaption(IContainer container)
		{
			container.Add(this);
			InitializeLogic();
		}

		private void InitializeLogic()
		{
			InitializeComponent();
			SetStyle();
			RegisterEventHandlers();
		}

		private void SetStyle()
		{
			base.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
			if (this.Parent != null)
			{
				mFont = new Font(this.Parent.Font, FontStyle.Bold);
			}
			else
			{
				mFont = new Font(this.Font, FontStyle.Bold);
			}
		}

		private void RegisterEventHandlers()
		{
			DefaultLookAndFeel.OnSkinChanged += new EventHandler(DefaultLookAndFeel_OnSkinChanged);
		}

		#endregion

		#region Custom draw

		protected override void OnPaint(PaintEventArgs e)
		{
			if (Skin == null)
			{
			    base.OnPaint(e);

			    return;
			}

			base.OnPaintBackground(e);

			int imgCurrent = 0;

			#region Window parts
			Rectangle tLT = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Top, Skin.CachedProperties.FormCaptionSizingMargin.Left, Skin.CachedProperties.FormCaptionSizingMargin.Top);
			Rectangle tT = new Rectangle(this.ClientRectangle.Left + Skin.CachedProperties.FormCaptionSizingMargin.Left, this.ClientRectangle.Top, this.ClientRectangle.Width - Skin.CachedProperties.FormCaptionSizingMargin.Horizontal, Skin.CachedProperties.FormCaptionSizingMargin.Top);
			Rectangle tRT = new Rectangle(this.ClientRectangle.Right - Skin.CachedProperties.FormCaptionSizingMargin.Right, this.ClientRectangle.Top, Skin.CachedProperties.FormCaptionSizingMargin.Right, Skin.CachedProperties.FormCaptionSizingMargin.Top);
			Rectangle tLM = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Top + Skin.CachedProperties.FormCaptionSizingMargin.Top, Skin.CachedProperties.FormCaptionSizingMargin.Left, this.ClientRectangle.Height - Skin.CachedProperties.FormCaptionSizingMargin.Vertical);
			Rectangle tM = new Rectangle(this.ClientRectangle.Left + Skin.CachedProperties.FormCaptionSizingMargin.Left, this.ClientRectangle.Top + Skin.CachedProperties.FormCaptionSizingMargin.Top, this.ClientRectangle.Width - Skin.CachedProperties.FormCaptionSizingMargin.Horizontal, this.ClientRectangle.Height - Skin.CachedProperties.FormCaptionSizingMargin.Vertical);
			Rectangle tRM = new Rectangle(this.ClientRectangle.Right - Skin.CachedProperties.FormCaptionSizingMargin.Right, this.ClientRectangle.Top + Skin.CachedProperties.FormCaptionSizingMargin.Top, Skin.CachedProperties.FormCaptionSizingMargin.Right, this.ClientRectangle.Height - Skin.CachedProperties.FormCaptionSizingMargin.Vertical);
			Rectangle tLB = new Rectangle(this.ClientRectangle.Left, this.ClientRectangle.Bottom - Skin.CachedProperties.FormCaptionSizingMargin.Bottom, Skin.CachedProperties.FormCaptionSizingMargin.Left, Skin.CachedProperties.FormCaptionSizingMargin.Bottom);
			Rectangle tB = new Rectangle(this.ClientRectangle.Left + Skin.CachedProperties.FormCaptionSizingMargin.Left, this.ClientRectangle.Bottom - Skin.CachedProperties.FormCaptionSizingMargin.Bottom, this.ClientRectangle.Width - Skin.CachedProperties.FormCaptionSizingMargin.Horizontal, Skin.CachedProperties.FormCaptionSizingMargin.Bottom);
			Rectangle tRB = new Rectangle(this.ClientRectangle.Right - Skin.CachedProperties.FormCaptionSizingMargin.Right, this.ClientRectangle.Bottom - Skin.CachedProperties.FormCaptionSizingMargin.Bottom, Skin.CachedProperties.FormCaptionSizingMargin.Right, Skin.CachedProperties.FormCaptionSizingMargin.Bottom);
			#endregion

			#region Drawing

			Image iLT = Skin.CachedProperties.FormCaptionImageLT[imgCurrent];
			Image iT = Skin.CachedProperties.FormCaptionImageT[imgCurrent];
			Image iRT = Skin.CachedProperties.FormCaptionImageRT[imgCurrent];
			Image iLM = Skin.CachedProperties.FormCaptionImageLM[imgCurrent];
			Image iM = Skin.CachedProperties.FormCaptionImageM[imgCurrent];
			Image iRM = Skin.CachedProperties.FormCaptionImageRM[imgCurrent];
			Image iLB = Skin.CachedProperties.FormCaptionImageLB[imgCurrent];
			Image iB = Skin.CachedProperties.FormCaptionImageB[imgCurrent];
			Image iRB = Skin.CachedProperties.FormCaptionImageRB[imgCurrent];

			e.Graphics.PixelOffsetMode = PixelOffsetMode.None;

			if (Skin.CachedProperties.FormCaptionSizingMargin.Left != 0 && Skin.CachedProperties.FormCaptionSizingMargin.Top != 0)
				e.Graphics.DrawImage(iLT, tLT, new Rectangle(1, 1, iLT.Width - 2, iLT.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Top != 0)
				e.Graphics.DrawImage(iT, tT, new Rectangle(1, 1, iT.Width - 2, iT.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Right != 0 && Skin.CachedProperties.FormCaptionSizingMargin.Top != 0)
				e.Graphics.DrawImage(iRT, tRT, new Rectangle(1, 1, iRT.Width - 2, iRT.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Left != 0)
				e.Graphics.DrawImage(iLM, tLM, new Rectangle(1, 1, iLM.Width - 2, iLM.Height - 2), GraphicsUnit.Pixel);
			e.Graphics.DrawImage(iM, tM, new Rectangle(1, 1, iM.Width - 2, iM.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Right != 0)
				e.Graphics.DrawImage(iRM, tRM, new Rectangle(1, 1, iRM.Width - 2, iRM.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Left != 0 && Skin.CachedProperties.FormCaptionSizingMargin.Bottom != 0)
				e.Graphics.DrawImage(iLB, tLB, new Rectangle(1, 1, iLB.Width - 2, iLB.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Bottom != 0)
				e.Graphics.DrawImage(iB, tB, new Rectangle(1, 1, iB.Width - 2, iB.Height - 2), GraphicsUnit.Pixel);
			if (Skin.CachedProperties.FormCaptionSizingMargin.Right != 0 && Skin.CachedProperties.FormCaptionSizingMargin.Bottom != 0)
				e.Graphics.DrawImage(iRB, tRB, new Rectangle(1, 1, iRB.Width - 2, iRB.Height - 2), GraphicsUnit.Pixel);

			#endregion


			// calculating buttons' properties

			int buttonSize = this.Size.Height - Skin.CachedProperties.FormCaptionContentMargin.Top - this.Skin.CachedProperties.FormCaptionContentMargin.Bottom;
			int buttonX = this.Size.Width - buttonSize - this.Skin.CachedProperties.FormCaptionContentMargin.Right;

			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).CloseButton)
			{
				this.formButtonClose.Location = new Point(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top);
				this.formButtonClose.Size = new System.Drawing.Size(buttonSize, buttonSize);
				this.formButtonClose.Visible = true;
				buttonX -= buttonSize;
			}
			else
				this.formButtonClose.Visible = false;

			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).MaximizeButton)
			{
				this.formButtonMaximize.Location = new Point(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top);
				this.formButtonMaximize.Size = new System.Drawing.Size(buttonSize, buttonSize);
				this.formButtonMaximize.Visible = true;
				buttonX -= buttonSize;
			}
			else
				this.formButtonMaximize.Visible = false;

			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).RestoreButton)
			{
				this.formButtonRestore.Location = new Point(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top);
				this.formButtonRestore.Size = new System.Drawing.Size(buttonSize, buttonSize);
				this.formButtonRestore.Visible = true;
				buttonX -= buttonSize;
			}
			else
				this.formButtonRestore.Visible = false;

			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).MinimizeButton)
			{
				this.formButtonMinimize.Location = new Point(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top);
				this.formButtonMinimize.Size = new System.Drawing.Size(buttonSize, buttonSize);
				this.formButtonMinimize.Visible = true;
				buttonX -= buttonSize;
			}
			else
				this.formButtonMinimize.Visible = false;

			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).HelpButton)
			{
				this.formButtonHelp.Location = new Point(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top);
				this.formButtonHelp.Size = new System.Drawing.Size(buttonSize, buttonSize);
				this.formButtonHelp.Visible = true;
				buttonX -= buttonSize;
			}
			else
				this.formButtonHelp.Visible = false;


			buttonX = Skin.CachedProperties.FormCaptionContentMargin.Left;

			// drawing icon
			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).DrawIcon)
			{
				e.Graphics.DrawImage(this.ParentForm.Icon.ToBitmap(), new Rectangle(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top, buttonSize, buttonSize),
					new Rectangle(0, 0, this.ParentForm.Icon.Width, this.ParentForm.Icon.Height), GraphicsUnit.Pixel);

				buttonX += buttonSize;
			}

			// drawing caption's text
			SizeF sF = e.Graphics.MeasureString(this.ParentForm.Text, mFont);
			int diff = (int)((buttonSize - sF.Height) / 2);
			e.Graphics.TextRenderingHint = Skin.TextRenderingHint;
			e.Graphics.DrawString(this.ParentForm.Text, mFont, new SolidBrush(Skin.CachedProperties.FormForeColor), new PointF(buttonX, Skin.CachedProperties.FormCaptionContentMargin.Top + diff));
			this.MinimumSize = new System.Drawing.Size((int)sF.Width + buttonX + buttonSize, (int)sF.Height);
		}

		#endregion

		#region Events

		void DefaultLookAndFeel_OnSkinChanged(object sender, EventArgs e)
		{
			SetStyle();
			Invalidate(true);
		}

		#endregion

		#region ISkinnable Members

		/// <summary>
		/// Use default skin?
		/// </summary>
		[Category("Look && feel")]
		public bool UseDefaultSkin
		{
			get
			{
				return mUseDefaultSkin;
			}
			set
			{
				mUseDefaultSkin = value;
				DefaultLookAndFeel_OnSkinChanged(this, null);
			}
		}

		/// <summary>
		/// Used skin
		/// </summary>
		[Category("Look && feel")]
		public Skin Skin
		{
			get
			{
				if (this.UseDefaultSkin)
				{
					return DefaultLookAndFeel.Skin;
				}

				return mSkin;
			}
			set
			{
				mSkin = value;
				Invalidate();
			}
		}

		#endregion

		private void formButtonClose_Click(object sender, EventArgs e)
		{
			this.ParentForm.Close();
		}

		private void formButtonClose_MouseMove(object sender, MouseEventArgs e)
		{
			this.formButtonClose.Cursor = System.Windows.Forms.Cursors.Default;
		}

		private void formButtonMaximize_Click(object sender, EventArgs e)
		{
            this.ParentForm.FormBorderStyle = FormBorderStyle.FixedSingle;
			this.ParentForm.WindowState = FormWindowState.Maximized;
            this.ParentForm.FormBorderStyle = FormBorderStyle.None;
		}

		private void formButtonMinimize_Click(object sender, EventArgs e)
		{
			this.ParentForm.WindowState = FormWindowState.Minimized;
		}

		private void formButtonRestore_Click(object sender, EventArgs e)
		{
			this.ParentForm.WindowState = FormWindowState.Normal;
		}

		private void formButtonHelp_Click(object sender, EventArgs e)
		{
			// TODO
		}

		private void FormCaption_DoubleClick(object sender, EventArgs e)
		{
			if ((this.ParentForm as SBPweb.Controls.Windows.Common.Form).MaximizeButton)
			{
				if (this.ParentForm.WindowState == FormWindowState.Normal)
					this.ParentForm.WindowState = FormWindowState.Maximized;
				else
					this.ParentForm.WindowState = FormWindowState.Normal;
			}
		}

	}
}
